﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace dasBlog.Storage.Configuration
{
    public sealed class NodesSection : ConfigurationSection
    {
        // Fields
        private static ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection();
        private static readonly ConfigurationProperty _propNodes = new ConfigurationProperty(null, typeof(NodeElementCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);

        // Methods
        static NodesSection()
        {
            _properties.Add(_propNodes);
        }

        // Properties
        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                return _properties;
            }
        }

        [ConfigurationProperty("", IsDefaultCollection = true)]
        public NodeElementCollection Nodes
        {
            get
            {
                return (NodeElementCollection)base[_propNodes];
            }
        }
    }

    public sealed class NodeElementCollection : ConfigurationElementCollection
    {
        // Methods
        public void Add(NodeElement element)
        {
            this.BaseAdd(element);
        }

        public void Clear()
        {
            base.BaseClear();
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new NodeElement();
        }

        public NodeElement Get(string elementKey)
        {
            return (NodeElement)base.BaseGet(elementKey);
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((NodeElement)element).Key;
        }

        public void Remove(NodeElement element)
        {
            base.BaseRemove(this.GetElementKey(element));
        }

        // Properties
        public override ConfigurationElementCollectionType CollectionType
        {
            get
            {
                return ConfigurationElementCollectionType.BasicMap;
            }
        }

        protected override string ElementName
        {
            get
            {
                return "node";
            }
        }
    }

    public sealed class NodeElement : ConfigurationElement
    {
        // Fields
        private static ConfigurationPropertyCollection _properties =
            new ConfigurationPropertyCollection();
        private static readonly ConfigurationProperty _propName =
            new ConfigurationProperty("name", typeof(string), "",
                ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired);
        private static readonly ConfigurationProperty _propProvider =
            new ConfigurationProperty("provider", typeof(string), "",
                ConfigurationPropertyOptions.None);
        private static readonly ConfigurationProperty _propClient =
            new ConfigurationProperty("client", typeof(string), "",
                ConfigurationPropertyOptions.None);
        private static readonly ConfigurationProperty _propClientCredential =
            new ConfigurationProperty("clientCredential", typeof(string), "",
                ConfigurationPropertyOptions.None);
        private static readonly ConfigurationProperty _propInitData =
            new ConfigurationProperty("initData", typeof(string), null,
                ConfigurationPropertyOptions.None);

        // Methods
        static NodeElement()
        {
            _properties.Add(_propName);
            _properties.Add(_propProvider);
            _properties.Add(_propClient);
            _properties.Add(_propClientCredential);
            _properties.Add(_propInitData);
        }

        public NodeElement()
        {
        }

        public NodeElement(string name, string provider, string initData)
            : this()
        {
            this.Name = name;
            this.Provider = provider;
            this.InitData = initData;
        }

        public override bool Equals(object providerCredentials)
        {
            NodeElement element = providerCredentials as NodeElement;
            if ((element != null) && base.Equals(providerCredentials))
            {
                return object.Equals(this.Name, element.Name);
            }
            return false;
        }

        public override int GetHashCode()
        {
            return (base.GetHashCode() ^ this.Provider.GetHashCode());
        }

        // Properties
        internal string Key
        {
            get
            {
                return this.Name;
            }
        }

        [ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
        public string Name
        {
            get
            {
                return (string)base[_propName];
            }
            set
            {
                base[_propName] = value;
            }
        }

        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                return _properties;
            }
        }

        [ConfigurationProperty("provider", IsRequired = false, DefaultValue = null)]
        public string Provider
        {
            get
            {
                return (string)base[_propProvider];
            }
            set
            {
                base[_propProvider] = value;
            }
        }

        [ConfigurationProperty("client", IsRequired = false, DefaultValue = null)]
        public string Client
        {
            get
            {
                return (string)base[_propClient];
            }
            set
            {
                base[_propClient] = value;
            }
        }

        [ConfigurationProperty("clientCredential", IsRequired = false, DefaultValue = null)]
        public string ClientCredential
        {
            get
            {
                return (string)base[_propClientCredential];
            }
            set
            {
                base[_propClientCredential] = value;
            }
        }

        [ConfigurationProperty("initData", IsRequired = false, DefaultValue = null)]
        public string InitData
        {
            get
            {
                return (string)base[_propInitData];
            }
            set
            {
                base[_propInitData] = value;
            }
        }

    }

}
